home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 681 / term / source.lha / StringHook.c < prev    next >
C/C++ Source or Header  |  1992-05-09  |  7KB  |  347 lines

  1. /*
  2. **    $Id: StringHook.c,v 1.2 92/04/21 16:59:47 olsen Sta Locker: olsen $
  3. **    $Revision: 1.2 $
  4. **    $Date: 92/04/21 16:59:47 $
  5. **
  6. **    Custom string gadget editing hook routines
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* ClipServer():
  15.      *
  16.      *    Quiet background process which saves data to the clipboard
  17.      *    or fills a buffer with fresh clipboard data.
  18.      */
  19.  
  20. VOID __saveds
  21. ClipServer()
  22. {
  23.     if(ClipPort = CreateMsgPort())
  24.     {
  25.         ULONG         Mask;
  26.         struct Message    *ClipMsg;
  27.         UBYTE        *Buffer;
  28.         BYTE         Terminated = FALSE;
  29.  
  30.         Signal(ThisProcess,SIGBREAKF_CTRL_C);
  31.  
  32.         while(!Terminated)
  33.         {
  34.             Mask = Wait(SIGBREAKF_CTRL_C | (1 << ClipPort -> mp_SigBit));
  35.  
  36.             if(Mask & SIGBREAKF_CTRL_C)
  37.                 Terminated = TRUE;
  38.  
  39.             if(Mask & (1 << ClipPort -> mp_SigBit))
  40.             {
  41.                 while(ClipMsg = GetMsg(ClipPort))
  42.                 {
  43.                     Buffer = ClipMsg -> mn_Node . ln_Name;
  44.  
  45.                     if(Buffer[0])
  46.                         SaveClip(Buffer,strlen(Buffer));
  47.                     else
  48.                     {
  49.                         WORD Len = LoadClip(Buffer,256);
  50.  
  51.                         Buffer[Len] = 0;
  52.                     }
  53.  
  54.                     ReplyMsg(ClipMsg);
  55.                 }
  56.             }
  57.         }
  58.  
  59.         DeleteMsgPort(ClipPort);
  60.     }
  61.  
  62.     Forbid();
  63.  
  64.     ClipProcess = NULL;
  65.  
  66.     Signal(ThisProcess,SIGBREAKF_CTRL_C);
  67. }
  68.  
  69.     /* CommandKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  70.      *
  71.      *    This routine is called whenever input passes through
  72.      *    a `term' string gadget. It releases the currently
  73.      *    active string gadget as soon as the Right-Amiga-key is
  74.      *    pressed (user is about to select a menu item).
  75.      */
  76.  
  77. VOID __saveds __asm
  78. CommandKey(register __a0 struct Hook *Hook,register __a1 ULONG *Msg,register __a2 struct SGWork *Work)
  79. {
  80.     if(Msg[0] == SGH_KEY)
  81.     {
  82.             /* Simple: activate the next gadget if
  83.              * return is pressed in the current one.
  84.              */
  85.  
  86.         if(Work -> Actions & SGA_END)
  87.         {
  88.             if(!(Work -> GadgetInfo -> gi_Window -> Flags & WFLG_RMBTRAP))
  89.                 Work -> Actions |= SGA_NEXTACTIVE;
  90.             else
  91.                 ActiveGadget = NULL;
  92.         }
  93.  
  94.             /* This looks like a built-in command. */
  95.  
  96.         if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_RCOMMAND)
  97.         {
  98.                 /* Amiga+C = Copy contents of string
  99.                  *           gadget to the clipboard.
  100.                  */
  101.  
  102.             if(Work -> Code == 'c')
  103.             {
  104.                 Work -> Actions &= ~SGA_USE;
  105.                 Work -> Actions |= SGA_BEEP;
  106.  
  107.                     /* Valid buffer contents? */
  108.  
  109.                 if(Work -> PrevBuffer[0])
  110.                 {
  111.                     struct MsgPort *ReplyPort;
  112.  
  113.                         /* Post a message... */
  114.  
  115.                     if(ReplyPort = CreateMsgPort())
  116.                     {
  117.                         struct Message ClipMessage;
  118.  
  119.                         ClipMessage . mn_Node . ln_Name    = Work -> PrevBuffer;
  120.                         ClipMessage . mn_ReplyPort    = ReplyPort;
  121.                         ClipMessage . mn_Length        = sizeof(struct Message);
  122.  
  123.                         PutMsg(ClipPort,&ClipMessage);
  124.  
  125.                         WaitPort(ReplyPort);
  126.  
  127.                         GetMsg(ReplyPort);
  128.  
  129.                         DeleteMsgPort(ReplyPort);
  130.  
  131.                         Work -> Actions &= ~SGA_BEEP;
  132.                     }
  133.                 }
  134.  
  135.                 return;
  136.             }
  137.  
  138.                 /* Amiga+V = Insert current clipboard
  139.                  *           contents at cursor position.
  140.                  */
  141.  
  142.             if(Work -> Code == 'v')
  143.             {
  144.                 Work -> Actions &= ~SGA_USE;
  145.                 Work -> Actions |= SGA_BEEP;
  146.  
  147.                     /* Don't paste to integer gadgets
  148.                      * (it could confuse Intuition if
  149.                      *  the buffer contained non-numeric
  150.                      *  symbols...).
  151.                      */
  152.  
  153.                 if(!(Work -> Gadget -> Activation & GACT_LONGINT))
  154.                 {
  155.                     struct MsgPort *ReplyPort;
  156.  
  157.                         /* Post a message... */
  158.  
  159.                     if(ReplyPort = CreateMsgPort())
  160.                     {
  161.                         STATIC UBYTE    Buffer[2048];
  162.                         struct Message    ClipMessage;
  163.  
  164.                         Buffer[0] = 0;
  165.  
  166.                         ClipMessage . mn_Node . ln_Name    = &Buffer[0];
  167.                         ClipMessage . mn_ReplyPort    = ReplyPort;
  168.                         ClipMessage . mn_Length        = sizeof(struct Message);
  169.  
  170.                         PutMsg(ClipPort,&ClipMessage);
  171.  
  172.                         WaitPort(ReplyPort);
  173.  
  174.                         GetMsg(ReplyPort);
  175.  
  176.                         DeleteMsgPort(ReplyPort);
  177.  
  178.                             /* Anything in the buffer? */
  179.  
  180.                         if(Buffer[0])
  181.                         {
  182.                             WORD Len = strlen(Buffer);
  183.  
  184.                                 /* Insert as many characters as we can. */
  185.  
  186.                             while(Len > 0 && Work -> NumChars + Len > Work -> StringInfo -> MaxChars)
  187.                                 Len--;
  188.  
  189.                                 /* Any characters left? */
  190.  
  191.                             if(Len > 0)
  192.                             {
  193.                                 STATIC UBYTE OtherBuffer[2048];
  194.  
  195.                                     /* Provide null-termination. */
  196.  
  197.                                 Buffer[Len] = 0;
  198.  
  199.                                     /* Set up undo buffer correctly. */
  200.  
  201.                                 if(Work -> StringInfo -> UndoBuffer)
  202.                                     strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);
  203.  
  204.                                 Work -> StringInfo -> UndoPos = --Work -> BufferPos;
  205.  
  206.                                     /* Save the characters before the cursor. */
  207.  
  208.                                 if(Work -> BufferPos)
  209.                                     CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);
  210.  
  211.                                     /* Provide null-termination. */
  212.  
  213.                                 OtherBuffer[Work -> BufferPos] = 0;
  214.  
  215.                                     /* Append the clipboard data. */
  216.  
  217.                                 strcat(OtherBuffer,Buffer);
  218.  
  219.                                     /* Append the characters following the cursor. */
  220.  
  221.                                 strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);
  222.  
  223.                                     /* = new work buffer. */
  224.  
  225.                                 strcpy(Work -> WorkBuffer,OtherBuffer);
  226.  
  227.                                     /* Fiddle with some cursor data. */
  228.  
  229.                                 Work -> BufferPos += Len;
  230.                                 Work -> NumChars    += Len;
  231.  
  232.                                     /* And that's it... */
  233.  
  234.                                 Work -> Actions    |= SGA_USE;
  235.                                 Work -> EditOp     = EO_BIGCHANGE;
  236.  
  237.                                 Work -> Actions &= ~SGA_BEEP;
  238.                             }
  239.                         }
  240.                         else
  241.                             Work -> Actions &= ~SGA_BEEP;
  242.                     }
  243.                 }
  244.  
  245.                 return;
  246.             }
  247.         }
  248.  
  249.         if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
  250.         {
  251.             if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
  252.                 return;
  253.             else
  254.             {
  255.                 Work -> Actions |= (SGA_END|SGA_REUSE);
  256.                 Work -> Actions &= ~(SGA_USE|SGA_BEEP);
  257.  
  258.                 CommandWindow = Work -> GadgetInfo -> gi_Window;
  259.                 CommandGadget = Work -> Gadget;
  260.             }
  261.         }
  262.  
  263.             /* The user pressed the cursor-right key to
  264.              * move the cursor to the next word in the buffer.
  265.              */
  266.  
  267.         if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  268.         {
  269.             if(Work -> BufferPos != Work -> NumChars)
  270.             {
  271.                 WORD i,Position = -1;
  272.  
  273.                 for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
  274.                 {
  275.                     if(Work -> WorkBuffer[i] == ' ')
  276.                     {
  277.                         for( ; i < Work -> NumChars ; i++)
  278.                         {
  279.                             if(Work -> WorkBuffer[i] != ' ')
  280.                             {
  281.                                 Position = i;
  282.                                 break;
  283.                             }
  284.                         }
  285.  
  286.                         break;
  287.                     }
  288.                 }
  289.  
  290.                 if(Position != -1)
  291.                     Work -> BufferPos = Position;
  292.                 else
  293.                     Work -> BufferPos = Work -> NumChars;
  294.  
  295.                 Work -> EditOp = EO_MOVECURSOR;
  296.             }
  297.         }
  298.  
  299.             /* The user pressed the cursor-right key to
  300.              * move the cursor to the previous word in the buffer.
  301.              */
  302.  
  303.         if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  304.         {
  305.             if(Work -> BufferPos)
  306.             {
  307.                 WORD i,Position = -1;
  308.  
  309.                 for(i = Work -> BufferPos ; i >= 0 ; i--)
  310.                 {
  311.                     if(Work -> WorkBuffer[i] != ' ')
  312.                     {
  313.                         Position = i;
  314.                         break;
  315.                     }
  316.                 }
  317.  
  318.                 if(Position == -1)
  319.                     Position = 0;
  320.  
  321.                 if(Position)
  322.                 {
  323.                     i = Position;
  324.  
  325.                     Position = -1;
  326.  
  327.                     for( ; i >= 0 ; i--)
  328.                     {
  329.                         if(Work -> WorkBuffer[i] == ' ')
  330.                         {
  331.                             Position = i + 1;
  332.                             break;
  333.                         }
  334.                     }
  335.                 }
  336.  
  337.                 if(Position != -1)
  338.                     Work -> BufferPos = Position;
  339.                 else
  340.                     Work -> BufferPos = 0;
  341.  
  342.                 Work -> EditOp = EO_MOVECURSOR;
  343.             }
  344.         }
  345.     }
  346. }
  347.